package com.lyh.config;

import com.lyh.mapper.UserMapper;
import com.lyh.pojo.User;
import com.lyh.utils.RegexUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;


/**
 * 自定义realm实现
 */
public class CustomizeRealm extends AuthorizingRealm {

    @Autowired
    UserMapper userMapper;

    /**
     * 自定义授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 获取username
        String principal = principalCollection.getPrimaryPrincipal().toString();

        //根据身份信息查询用户角色
        SimpleAuthorizationInfo authorization = new SimpleAuthorizationInfo();
        //如果用户已激活, 则添加active角色, 后期该用户买票需要active角色才可以买票
        if ( userMapper.queryActive(principal) == 1 ) {
            //已激活
            authorization.addRole("active");
        }
        return authorization;
    }

    /**
     * 自定义认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //在token中获取用户名信息
        String principal = token.getPrincipal().toString();//getPrincipal返回的是char数组

        if(!RegexUtils.notNull(principal))
            return null;

        User userFromDB = null;

        //判断这个用户的标识符是手机号码还是密码
        if(RegexUtils.checkPhone(principal))
            userFromDB = userMapper.queryUserByPhone(principal);
        else if(RegexUtils.checkUsernameAndPassword(principal))
            userFromDB = userMapper.queryUserByUsername(principal);

        if(userFromDB!=null) {

            //查出用户名,就校验密码
            //参数:1.用户名 2.从数据库中查出加密过的密码 3.Salt 4.当前Realm名
            return new SimpleAuthenticationInfo(
                    userFromDB, //直接存放整个用户对象
                    userFromDB.getPassword(),
                    ByteSource.Util.bytes(userFromDB.getSalt()),
                    this.getName());
            //如果不返回这个,会报错未知账号
        } else {
            //无法查到用户
            return null; //返回null会自动抛出用户名不存在异常
        }

    }
}